﻿using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using Newtonsoft.Json;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Security.Cryptography;
using System.Collections.Specialized;

namespace BrnMall.Sdk.WeiXin.Tool
{
    public class RestHttp
    {
        public static T Get<T>(string url)
        {
            var request = (HttpWebRequest)WebRequest.Create(url);
            return Get<T>(url, request);
        }
     
        public static T Get<T>(string url, HttpWebRequest request)
        {
            Trace.TraceInformation(url);
            request.Method = "GET";
            var response = (HttpWebResponse)request.GetResponse();
            var resStream = response.GetResponseStream();
            if (resStream == null) return default(T);
            var wwwresult = new StreamReader(resStream).ReadToEnd();
            Trace.TraceInformation(wwwresult);
            return JsonConvert.DeserializeObject<T>(wwwresult);
        }

        public static string Request(string url)
        {
            Trace.TraceInformation(url);

            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";
            var response = (HttpWebResponse)request.GetResponse();
            var resStream = response.GetResponseStream();
            if (resStream == null) return string.Empty;
            var wwwresult = new StreamReader(resStream).ReadToEnd();
            Trace.TraceInformation(wwwresult);
            return wwwresult;
        }
        public static T Post<T>(string url, string data)
        {
            Trace.TraceInformation(url);
            Trace.TraceInformation(data);
            var request = (HttpWebRequest)WebRequest.Create(url);
            var postData = Encoding.UTF8.GetBytes(data);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = postData.Length;
            using (var stream = request.GetRequestStream())
            {
                stream.Write(postData, 0, postData.Length);
            }
            var response = (HttpWebResponse)request.GetResponse();
            var resStream = response.GetResponseStream();
            if (resStream == null) return default(T);
            var wwwresult = new StreamReader(resStream).ReadToEnd();
            Trace.TraceInformation(wwwresult);
            return JsonConvert.DeserializeObject<T>(wwwresult);
        }

        public static string Post(string url, string data)
        {
            return Post(url, data, "application/x-www-form-urlencoded");
        }
        public static string JsonPost(string url, string data)
        {
            return Post(url, data, "application/json");
        }

        private static string Post(string url, string data,string contentType)
        {
            Trace.TraceInformation(url);
            Trace.TraceInformation(data);
            var request = (HttpWebRequest)WebRequest.Create(url);
            var postData = Encoding.UTF8.GetBytes(data);
            request.Method = "POST";
            request.ContentType = contentType;
            request.ContentLength = postData.Length;
            using (var stream = request.GetRequestStream())
            {
                stream.Write(postData, 0, postData.Length);
            }
            var response = (HttpWebResponse)request.GetResponse();
            var resStream = response.GetResponseStream();
            if (resStream == null) return string.Empty;
            var wwwresult = new StreamReader(resStream).ReadToEnd();
            Trace.TraceInformation(wwwresult);
            return wwwresult;
        }
        
        public static string Upload(string url, string filePath, string postData = "")
        {
            var result = string.Empty;
            var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
            byte[] boundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;
            request.Method = "POST";
            request.Credentials = CredentialCache.DefaultCredentials;
            request.CookieContainer = new CookieContainer();
            Stream reqStream = request.GetRequestStream();
            //表单数据            
            if (postData != "")
            {
                string[] arrydata = postData.Split('&');
                var formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
                foreach (string key in arrydata)
                {
                    reqStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                    string formitem = string.Format(formdataTemplate, key.Split('=')[0].ToString(), key.Split('=')[1].ToString());
                    byte[] formitembytes = Encoding.UTF8.GetBytes(formitem);
                    reqStream.Write(formitembytes, 0, formitembytes.Length);
                }
            }
            reqStream.Write(boundaryBytes, 0, boundaryBytes.Length);
            var header = string.Format("Content-Disposition:form-data;name=\"file.jpg\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", filePath);
            byte[] headerBytes = Encoding.UTF8.GetBytes(header);
            reqStream.Write(headerBytes, 0, headerBytes.Length);

            int index = 0;
            byte[] buffer = new byte[4096];
            using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                while ((index = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                {
                    reqStream.Write(buffer, 0, index);
                }
            }
            reqStream.Write(boundaryBytes, 0, boundaryBytes.Length);
            reqStream.Close();

            var response = request.GetResponse();
            var resStream = response.GetResponseStream();
            result = new StreamReader(resStream).ReadToEnd();
            resStream.Close();
            return result;
        }

        public static string GetMapPath(string path)
        {
            return HttpContext.Current != null ? HttpContext.Current.Server.MapPath(path) : System.Web.Hosting.HostingEnvironment.MapPath(path);
        }
    }
}